package ding.com.multifragment.struct;

import android.text.TextUtils;

import java.util.HashMap;

import ding.com.multifragment.FunctionException;

/**
 * Created by ding on 2017/9/29.
 */

public class FuntionsManager {
    private static FuntionsManager ourInstance ;
    private HashMap<String, FuntionNoParamNoResult> mFuntionNoParamNoResult;
    private HashMap<String, FuntionWithParamAndResult> mFuntionWithParamAndResult;
    private HashMap<String, FuntionWithResultOnly> mFuntionWithResultOnly;
    private HashMap<String, FuntionWithParamNoResult> mFuntionWithParamNoResult;

    private FuntionsManager() {
        mFuntionNoParamNoResult=new HashMap<>();
        mFuntionWithParamAndResult=new HashMap<>();
        mFuntionWithResultOnly=new HashMap<>();
        mFuntionWithParamNoResult=new HashMap<>();
    }
    public static FuntionsManager getInstance() {
        if (ourInstance==null){
            ourInstance = new FuntionsManager();
        }
        return ourInstance;
    }

    public FuntionsManager addFuntion(FuntionNoParamNoResult funtion){
        mFuntionNoParamNoResult.put(funtion.mFuntionName,funtion);
        return ourInstance;
    }
    public FuntionsManager addFuntion(FuntionWithParamAndResult funtion){
        mFuntionWithParamAndResult.put(funtion.mFuntionName,funtion);
        return ourInstance;
    }
    public FuntionsManager addFuntion(FuntionWithResultOnly funtion){
        mFuntionWithResultOnly.put(funtion.mFuntionName,funtion);
        return ourInstance;
    }
    public FuntionsManager addFuntion(FuntionWithParamNoResult funtion){
        mFuntionWithParamNoResult.put(funtion.mFuntionName,funtion);
        return ourInstance;
    }

    public void invokeFuntion(String funtionName){
        if (TextUtils.isEmpty(funtionName)){
            return ;
        }
        if (mFuntionNoParamNoResult !=null){
            FuntionNoParamNoResult f=mFuntionNoParamNoResult.get(funtionName);
            if (f!=null){
                f.function();
            }else {
                try {
                    throw new FunctionException("Has no this fuction: "+funtionName);
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }

        }
    }
    public <Param> void invokeFuntion(String funtionName,Param data){
        if (TextUtils.isEmpty(funtionName)){
            return ;
        }
        if (mFuntionWithParamNoResult !=null){
            FuntionWithParamNoResult f=mFuntionWithParamNoResult.get(funtionName);
            if (f!=null){
                f.function(data);
            }else {
                try {
                    throw new FunctionException("Has no this fuction: "+funtionName);
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    public <Result> Result invokeFuntion(String funtionName,Class<Result> c){
        if (TextUtils.isEmpty(funtionName)){
            return null;
        }
        if (mFuntionWithParamAndResult !=null){
            FuntionWithResultOnly f=mFuntionWithResultOnly.get(funtionName);
            if (f!=null){
                if (c!=null){
                    return c.cast(f.function());
                }else {
                    return (Result) f.function();
                }

            }else {
                try {
                    throw new FunctionException("Has no this fuction: "+funtionName);
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }

        }
        return null;
    }

    public <Result,Param> Result invokeFuntion(String funtionName,Param data,Class<Result> c){
        if (TextUtils.isEmpty(funtionName)){
            return null;
        }
        if (mFuntionWithParamAndResult !=null){
            FuntionWithParamAndResult f=mFuntionWithParamAndResult.get(funtionName);
            if (f!=null){
                if (c!=null){
                    return c.cast(f.function(data));
                }else {
                    return (Result) f.function(data);
                }

            }else {
                try {
                    throw new FunctionException("Has no this fuction: "+funtionName);
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }

        }
        return null;
    }


}
